home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / shells / flin-0.5 / flin-0 / flin-0.5.1 / menu.c < prev    next >
C/C++ Source or Header  |  1995-12-06  |  5KB  |  200 lines

  1. #ifdef HAVE_CONFIG_H
  2. #   include <config.h>
  3. #endif
  4.  
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <malloc.h>
  8.  
  9. #include "menu.h"
  10. #include "misc.h"
  11. #include "string.h"
  12.  
  13. struct token {
  14.    char *str;
  15.    int token, flags;
  16. };
  17.  
  18. struct token menu_tokens[] = {
  19.    {MENU_OP_TITLE, MENU_TITLE, NO_ARGS},
  20.    {MENU_OP_NOP, MENU_NOP, NO_ARGS},
  21.    {MENU_OP_EXIT, MENU_EXIT, NO_ARGS},
  22.    {MENU_OP_SUB, MENU_SUB, ARGS},
  23.    {MENU_OP_EXEC, MENU_EXEC, ARGS},
  24.    {MENU_OP_QUIT, MENU_QUIT, NO_ARGS},
  25.    {MENU_OP_ARGS, MENU_ARGS, PROMPT},
  26.    {NULL, NO_TOKEN, NO_ARGS}
  27. };
  28.  
  29. extern char delim;
  30. extern char comment;
  31.  
  32. static int get_token(char *name, int *flags) {
  33.    int i=0, found=0;
  34.  
  35.    while (menu_tokens[i].str) {
  36.       if (!strcasecmp(name, menu_tokens[i].str)) {
  37.      found = 1;
  38.      break;
  39.       }
  40.       i++;
  41.    }
  42.  
  43.    if (!found) {
  44.       *flags = 0;
  45.       return NO_TOKEN;
  46.    } else {
  47.       *flags = menu_tokens[i].flags;
  48.       return menu_tokens[i].token;
  49.    }
  50. }
  51.  
  52. static void alloc_items(struct menu_items **data, const char *line, int i) {
  53.    int worddex, flags;
  54.    char Word[MAX_WORD]; char *word = Word;
  55.    char errmess[MENU_BUFF];
  56.  
  57.    worddex = substr(line, word, delim);
  58.  
  59.    /* Advance past word */
  60.    line += worddex+1;
  61.  
  62.    if (!strlen(line))
  63.       return;
  64.    
  65.    /* Scan for tokens, then dissemate information */
  66.    if (((*data)->type = get_token(word, &flags)) == NO_TOKEN) {
  67.       sprintf(errmess, "No such token `%s'\n", word);
  68.       error(errmess, i);
  69.    }
  70.  
  71.    if ((worddex = substr(line,word,delim)) == -1)
  72.       error("Premature end-of-line\n",i);
  73.       
  74.    (*data)->name = (char *)chk_alloc(strlen(word)+1);
  75.    strcpy((*data)->name, word);
  76.  
  77.    switch (flags) {
  78.    case NO_ARGS:
  79.       (*data)->args = NULL;
  80.       (*data)->prompt = NULL;
  81.       break;
  82.    case ARGS:
  83.       line += worddex+1;
  84.  
  85.       if (substr(line,word,delim) == -1)
  86.      error("Premature end-of-line\n",i);
  87.  
  88.       (*data)->args = (char *)chk_alloc(strlen(word)+1);
  89.       strcpy((*data)->args, word);
  90.  
  91.       break;
  92.    case PROMPT:
  93.       line += worddex+1;
  94.  
  95.       if ((worddex = substr(line,word,delim)) == -1)
  96.      error("Premature end-of-line\n",i);
  97.  
  98.       (*data)->args = (char *)chk_alloc(strlen(word)+1);
  99.       strcpy((*data)->args, word);
  100.  
  101.       line += worddex+1;
  102.  
  103.       /* Read in additional ARGS information, an argument prompt. */
  104.       if ((worddex = substr(line,word,delim)) == -1) {
  105.      /* did not find another delimited string. */
  106.  
  107.      (*data)->prompt = (char *)chk_alloc(strlen(DEFAULT_PROMPT)+1);
  108.      strcpy((*data)->prompt, DEFAULT_PROMPT);
  109.       } else {
  110.      (*data)->prompt = (char *)chk_alloc(strlen(word)+1);
  111.      strcpy((*data)->prompt, word);
  112.       }
  113.  
  114.       break;
  115.    }
  116.    
  117.    /* Allocate another link */
  118.    (*data)->next = (struct menu_items*)chk_alloc(sizeof(struct menu_items));
  119.    (*data)->next->prev = *data;
  120.    *data = (*data)->next;
  121.    (*data)->next = NULL;
  122. }
  123.  
  124. static char *add_menu_lines(struct menu **menuptr, char *menufile, char *line, int *start_line) {
  125.    int i, index, menu_close;
  126.  
  127.    i = *start_line;
  128.    menu_close = 0;
  129.    while (!menu_close) {
  130.       /* Error on EOF, it doesnt belong here */
  131.       if ((index = getline(menufile, line)) == -1)
  132.      error("Premature end-of-file\n", i);
  133.       /* Advance past line */
  134.       menufile += index+1;
  135.       i++;
  136.  
  137.       strwhite(line);
  138.       if (*line == comment)
  139.      continue;
  140.  
  141.       /* Close menu on MENU_END, otherwise define node */
  142.       if (!strcasecmp(line, MENU_END)) {
  143.      menu_close = 1;
  144.       } else {
  145.      alloc_items(&((*menuptr)->data), line, i);
  146.       }
  147.    }
  148.  
  149.    /* Free last link */
  150.    if (!(*menuptr)->data->prev) {
  151.       free((*menuptr)->data);
  152.       (*menuptr)->data = NULL;
  153.    } else {
  154.       (*menuptr)->data = (*menuptr)->data->prev;
  155.       free((*menuptr)->data->next);
  156.       (*menuptr)->data->next = NULL;
  157.  
  158.       /* rewind linked list */
  159.       while ((*menuptr)->data->prev)
  160.       (*menuptr)->data = (*menuptr)->data->prev;
  161.    }
  162.  
  163.     *start_line = i;
  164.     return menufile;
  165. }
  166.  
  167. char *define_menu(struct menu **menuptr, char *menufile, char *line, int *i) {
  168.    char Word[MAX_WORD];
  169.    char *word = Word;
  170.  
  171. #ifdef DEBUG
  172.    printf("define_menu()\n");
  173. #endif
  174.    
  175.    if (substr(line, word, ' ') == 0)
  176.       error("Premature end-of-line\n", *i);
  177.  
  178.    /* Store menu name, for easy retrieval */
  179.    (*menuptr)->name = (char *)chk_alloc(strlen(word)+1);
  180.    strcpy((*menuptr)->name, word);
  181.  
  182.    /* Initialize menu.data structure */
  183.    (*menuptr)->data = (struct menu_items *)chk_alloc(sizeof(struct menu_items));
  184.    (*menuptr)->data->next = NULL;
  185.    (*menuptr)->data->prev = NULL;
  186.  
  187.    /* Loop through, defining menu, quit at MENU_END */
  188.    menufile = add_menu_lines(menuptr, menufile, line, i);
  189.  
  190.    /* Allocate another link */
  191.    (*menuptr)->next = (struct menu *)chk_alloc(sizeof(struct menu));
  192.    (*menuptr)->next->prev = *menuptr;
  193.    *menuptr = (*menuptr)->next;
  194.    (*menuptr)->next = NULL;
  195.    (*menuptr)->data = NULL;
  196.  
  197.    return menufile;
  198. }
  199.  
  200.